using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BitMango;
using BitMango.Diagnostics;
using JsonFx.Json;
using UnityEngine;

public static class PlaytomicCloud
{
    static PlaytomicCloud()
    {
        //Playtomic.Initialize(Context.BMPlatform.appID, Context.BMPlatform.appID + "_private", "http://playtomic.bitmango.com:3000/");
    }

    private static IEnumerator SendSaveLoadRequest(string section, string action, Dictionary<string, object> postdata, bool anonymousQuery, Action<Dictionary<string, object>, PResponse> callback)
    {
        postdata = PlaytomicCloud.PreparePostData(postdata, anonymousQuery);
        WWW www = PRequest.Prepare(section, action, postdata);
        yield return www;
        PResponse response = PRequest.Process(www);
        Dictionary<string, object> result = null;
        if (response.success)
        {
            result = response.json;
        }
        callback(result, response);
        yield break;
    }

    private static Dictionary<string, object> PreparePostData(Dictionary<string, object> postdata, bool anonymousQuery)
    {
        if (postdata == null)
        {
            postdata = new Dictionary<string, object>();
        }
        if (anonymousQuery)
        {
            postdata.Add("playerid", "admin");
        }
        else
        {
            postdata.Add("playerid", PlayerPrefs.GetString("MyFacebookId"));
        }
        return postdata;
    }

    public static void LoadAllData(Action<Dictionary<string, object>, PResponse> callback)
    {
        PlaytomicCloud.isLoading = true;
        Dictionary<string, object> dictionary = new Dictionary<string, object>();
        dictionary.Add("name", "gameData");
        Playtomic.API.StartCoroutine(PlaytomicCloud.SendSaveLoadRequest("playervars", "single", dictionary, false, delegate (Dictionary<string, object> dict, PResponse response)
        {
            PlaytomicCloud.isLoading = false;
            PlaytomicCloud.isLoaded = response.success;
            if (PlaytomicCloud.isLoaded)
            {
                Debugger.Assert(dict.ContainsKey("playervars"));
                if (dict.ContainsKey("playervars"))
                {
                    Dictionary<string, object>[] array = dict["playervars"] as Dictionary<string, object>[];
                    if (array != null)
                    {
                        Debugger.Assert(array.Length > 0);
                        PlaytomicCloud.localDict = (array[0]["value"] as Dictionary<string, object>);
                    }
                    else
                    {
                        response.success = false;
                    }
                }
                else
                {
                    response.success = false;
                }
            }
            if (!response.success)
            {
                UnityEngine.Debug.LogError("PlaytomicCloud.Load fail : " + response.errormessage);
            }
            if (callback != null)
            {
                callback(dict, response);
            }
        }));
    }

    public static void SaveAllData(Action<bool> callback)
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        Dictionary<string, object> dictionary = new Dictionary<string, object>();
        dictionary.Add("name", "gameData");
        dictionary.Add("value", PlaytomicCloud.localDict);
        Playtomic.API.StartCoroutine(PlaytomicCloud.SendSaveLoadRequest("playervars", "save", dictionary, false, delegate (Dictionary<string, object> dict, PResponse response)
        {
            if (callback != null)
            {
                if (!response.success)
                {
                    UnityEngine.Debug.LogError("PlaytomicCloud.Save fail : " + response.errormessage);
                }
                callback(response.success);
            }
        }));
    }

    public static bool IsLoaded
    {
        get
        {
            return PlaytomicCloud.isLoaded;
        }
    }

    public static void RemoveObjectForKey(string aKey)
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        PlaytomicCloud.localDict.Remove(aKey);
    }

    public static bool HasKey(string key)
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        return PlaytomicCloud.localDict.ContainsKey(key);
    }

    public static string StringForKey(string key)
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        return (string)PlaytomicCloud.localDict[key];
    }

    public static List<string> AllKeys()
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        return new List<string>(PlaytomicCloud.localDict.Keys);
    }

    public static void RemoveAll()
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        PlaytomicCloud.localDict.Clear();
    }

    public static void SetString(string aKey, string aString)
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        Debugger.Assert(!string.IsNullOrEmpty(aKey), "SetString key is null : " + aKey);
        if (!string.IsNullOrEmpty(aKey))
        {
            PlaytomicCloud.localDict[aKey] = aString;
        }
    }

    public static int IntForKey(string aKey)
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        return (int)PlaytomicCloud.localDict[aKey];
    }

    public static void SetInt(string aKey, int value)
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        PlaytomicCloud.localDict[aKey] = value;
    }

    public static bool BoolForKey(string aKey)
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        return (bool)PlaytomicCloud.localDict[aKey];
    }

    public static void SetBool(string aKey, bool value)
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        PlaytomicCloud.localDict[aKey] = value;
    }

    public static object ObjectForKey(string aKey)
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        return PlaytomicCloud.localDict[aKey];
    }

    public static void SetObject(string aKey, object value)
    {
        Debugger.Assert(PlaytomicCloud.isLoaded);
        PlaytomicCloud.localDict[aKey] = value;
    }

    private static void saveUserDataToCloudInternal(bool confirm, Action<bool> callback)
    {
        if (confirm)
        {
            ContextPoolAdapter.LoadAllContext();
            JsonFileSystem.SetFileSystem(new PlaytomicFileSystem());
            ContextPoolAdapter.SaveAllContext();
            JsonFileSystem.SetFileSystem(new ResourceFileSystem());
            PlaytomicCloud.SetString("lastSavedDevice", SystemInfo.deviceName);
            PlaytomicCloud.SetString("lastSavedTime", DateTime.Now.ToString());
            PlaytomicCloud.SaveAllData(delegate (bool success)
            {
                Platform.SafeCallback<bool>(callback, success);
            });
        }
        else
        {
            Platform.SafeCallback<bool>(callback, false);
        }
    }

    public static void SaveUserDataToCloud(Action<bool> callback)
    {
        PlaytomicCloud.isLoaded = true;
        if (PlaytomicCloud.HasKey("lastSavedDevice"))
        {
            string message = string.Format("cloud_save_warn".GetString(), PlaytomicCloud.StringForKey("lastSavedDevice"), PlaytomicCloud.StringForKey("lastSavedTime"));
            Platform.SystemAlert("PlaytomicCloud", message, "ok", "cancel", delegate (bool ok)
            {
                PlaytomicCloud.saveUserDataToCloudInternal(ok, callback);
            });
        }
        else
        {
            PlaytomicCloud.saveUserDataToCloudInternal(true, callback);
        }
    }

    private static void loadUserDataFromCloudInternal2(bool loadConfirmed, Action<bool> callback)
    {
        if (loadConfirmed)
        {
            JsonFileSystem.SetFileSystem(new PlaytomicFileSystem());
            ContextPoolAdapter.LoadAllContext();
            JsonFileSystem.SetFileSystem(new ResourceFileSystem());
            ContextPoolAdapter.SaveAllContext();
        }
        Platform.SafeCallback<bool>(callback, loadConfirmed);
    }

    private static IEnumerator loadUserDataFromCloudInternal(Action<bool> callback)
    {
        PlaytomicCloud.LoadAllData(null);
        while (PlaytomicCloud.isLoading)
        {
            yield return 0;
        }
        if (PlaytomicCloud.IsLoaded)
        {
            if (PlaytomicCloud.HasKey("lastSavedDevice"))
            {
                string message = string.Format("cloud_load_warn".GetString(), PlaytomicCloud.StringForKey("lastSavedDevice"), PlaytomicCloud.StringForKey("lastSavedTime"));
                Platform.SystemAlert("PlaytomicCloud", message, "ok", "cancel", delegate (bool ok)
                {
                    PlaytomicCloud.loadUserDataFromCloudInternal2(ok, callback);
                });
            }
            else
            {
                PlaytomicCloud.loadUserDataFromCloudInternal2(true, callback);
            }
        }
        else
        {
            Platform.SafeCallback<bool>(callback, false);
        }
        yield break;
    }

    public static void LoadUserDataFromCloud(Action<bool> callback)
    {
        Playtomic.API.StartCoroutine(PlaytomicCloud.loadUserDataFromCloudInternal(callback));
    }

    public static void LoadGameVariable(string varName, Action<object> callback)
    {
        Dictionary<string, object> dictionary = new Dictionary<string, object>();
        dictionary.Add("method", "select");
        string[] fields = varName.Split(new char[]
        {
            '.'
        });
        dictionary.Add("filter", new PlaytomicCloud.QueryFilter(fields[0]));
        if (fields.Length > 1)
        {
            Dictionary<string, object> dictionary2 = new Dictionary<string, object>();
            dictionary2["value." + string.Join(".", fields.Skip(1).ToArray<string>())] = 1;
            dictionary.Add("fields", dictionary2);
        }
        Playtomic.API.StartCoroutine(PlaytomicCloud.SendSaveLoadRequest("playervars", "query", dictionary, true, delegate (Dictionary<string, object> dict, PResponse response)
        {
            object obj = null;
            if (dict != null && dict.ContainsKey("playervars"))
            {
                Dictionary<string, object>[] array = dict["playervars"] as Dictionary<string, object>[];
                if (array != null)
                {
                    Debugger.Assert(array.Length > 0);
                    obj = array[0]["value"];
                    if (fields.Length > 1)
                    {
                        for (int i = 1; i < fields.Length; i++)
                        {
                            Dictionary<string, object> dictionary3 = obj as Dictionary<string, object>;
                            obj = dictionary3[fields[i]];
                        }
                    }
                }
            }
            if (callback != null)
            {
                callback(obj);
            }
        }));
    }

    public static void LoadGameVariable<T>(string varName, Action<T> callback) where T : class
    {
        PlaytomicCloud.LoadGameVariable(varName, delegate (object dict)
        {
            if (dict != null && callback != null)
            {
                string value = JsonWriter.Serialize(dict);
                callback(JsonReader.Deserialize<T>(value));
            }
            else
            {
                callback((T)((object)null));
            }
        });
    }

    public static void SaveGameVariable(string varName, object val, Action<object> callback)
    {
        Dictionary<string, object> dictionary = new Dictionary<string, object>();
        dictionary.Add("method", "update");
        string[] array = varName.Split(new char[]
        {
            '.'
        });
        Debugger.Assert(array.Length > 0);
        dictionary.Add("filter", new PlaytomicCloud.QueryFilter(array[0]));
        if (array.Length > 1)
        {
            Dictionary<string, object> dictionary2 = new Dictionary<string, object>();
            dictionary2["value." + string.Join(".", array.Skip(1).ToArray<string>())] = val;
            UnityEngine.Debug.Log("value." + string.Join(".", array.Skip(1).ToArray<string>()));
            Dictionary<string, object> dictionary3 = new Dictionary<string, object>();
            dictionary3["$set"] = dictionary2;
            dictionary.Add("doc", dictionary3);
        }
        Playtomic.API.StartCoroutine(PlaytomicCloud.SendSaveLoadRequest("playervars", "query", dictionary, true, delegate (Dictionary<string, object> dict, PResponse response)
        {
            if (!response.success)
            {
                UnityEngine.Debug.LogError(response.errormessage);
            }
            if (callback != null)
            {
                callback(response.success);
            }
        }));
    }

    private const string PRIVATE_KEY = "_private";

    //private const string API_URL = "http://playtomic.bitmango.com:3000/";

    private const string SECTION = "playervars";

    private const string SAVE = "save";

    private const string LOAD = "load";

    private const string QUERY = "query";

    private const string LOADSINGLE = "single";

    private static bool isLoaded = false;

    private static bool isLoading = false;

    private static Dictionary<string, object> localDict = new Dictionary<string, object>();

    private class QueryFilter
    {
        public QueryFilter(string _name)
        {
            this.publickey = PRequest.PUBLICKEY;
            this.name = _name;
        }

        public string publickey;

        public string playerid = "admin";

        public string name;
    }
}
